package com.yami.shop.rights.common.strategy.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yami.shop.bean.enums.RightsType;
import com.yami.shop.bean.event.AddRightsEvent;
import com.yami.shop.bean.event.TransferRightsEvent;
import com.yami.shop.rights.common.dao.PersonRightsMapper;
import com.yami.shop.rights.common.dto.PersonRightsDto;
import com.yami.shop.rights.common.model.*;
import com.yami.shop.rights.common.service.*;
import com.yami.shop.rights.common.strategy.PersonRightsStrategy;
import com.yami.shop.rights.common.vo.PersonnftRightsVo;
import com.yami.shop.security.common.util.AuthUserContext;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Log4j2
@Service
public class VoucherPersonRightsStrategyImpl implements PersonRightsStrategy {

    @Autowired
    private RightsExternalService rightsExternalService;
    @Autowired
    private RightsVoucherService rightsVoucherService;
    @Autowired
    private PersonRightsVoucherService personRightsVoucherService;
    @Autowired
    private ProdRightsExternalDataService prodRightsExternalDataService;
    @Autowired
    private ProdRightsService prodRightsService;
    @Autowired
    private RightsTransferRecordService rightsTransferRecordService;

    @Override
    public String rightsType() {
        return RightsType.VOUCHER_RIGHTS.value();
    }

    @Override
    public void savePersonRightsData(ProdRights dto) {
        // 修改 电子券使用状态
        LambdaUpdateWrapper<RightsExternal> rightsExternalLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        rightsExternalLambdaUpdateWrapper.eq(RightsExternal::getId, dto.getProdId());
        rightsExternalLambdaUpdateWrapper.set(RightsExternal::getStatus, "1");
        rightsExternalService.update(rightsExternalLambdaUpdateWrapper);

        // 删除抵扣券权益信息
        if(ObjectUtil.isNotEmpty(dto.getId())){
            QueryWrapper<RightsVoucher> rightsVoucherQueryWrapper = new QueryWrapper<>();
            rightsVoucherQueryWrapper.eq("rights_id",dto.getId());
            rightsVoucherService.remove(rightsVoucherQueryWrapper);
        }
        RightsVoucher rightsVoucher = BeanUtil.copyProperties(dto, RightsVoucher.class);
        rightsVoucher.setRightsId(dto.getId());
        // 新增抵扣券权益信息
        rightsVoucherService.save(rightsVoucher);
    }

    @Override
    public Long getSurplusTimes(long id) {
        QueryWrapper<PersonRightsVoucher> personRightsExternalQueryWrapper = new QueryWrapper<>();
        personRightsExternalQueryWrapper.eq("person_rights_id",id);
        personRightsExternalQueryWrapper.eq("status",0);
        List<PersonRightsVoucher> personRightsExternals = personRightsVoucherService.list(personRightsExternalQueryWrapper);
        return ObjectUtil.isNotEmpty(personRightsExternals) ? personRightsExternals.stream().mapToLong(PersonRightsVoucher::getTimes).sum() : 0L;
    }

    @Override
    public void addPersonRights(ProdRights prodRights, AddRightsEvent event, long personRightsId) {
        // 增加抵扣券权益
        log.info("增加抵扣券权益" + event.getUserId());
        // 获取抵扣券
        List<ProdRightsExternalData> prodRightsExternalDatas = prodRightsExternalDataService.getDataByCount(prodRights.getProdId(), prodRights.getDrawCount());
        // 新增抵扣券持有详情
        List<PersonRightsVoucher> personRightsExternals = new ArrayList<>();
        prodRightsExternalDatas.forEach(s -> {
            PersonRightsVoucher personRightsExternal = new PersonRightsVoucher();
            personRightsExternal.setExternalDataId(s.getId());
            personRightsExternal.setEffectiveTime(prodRights.getExchangeEndTime());
            personRightsExternal.setPersonRightsId(personRightsId);
            personRightsExternal.setTimes(1);
            // 获取抵扣券膨胀值
            RightsVoucher rightsVoucher = rightsVoucherService.getOne(new QueryWrapper<RightsVoucher>().eq("rights_id", prodRights.getId()));
            personRightsExternal.setExpansionData(rightsVoucher.getExpansionData());
            personRightsExternals.add(personRightsExternal);
        });
        personRightsVoucherService.saveBatch(personRightsExternals);
    }

    @Override
    public List<PersonRightsDto> verificationRights(JSONObject qrCodeData) {
        // 修改次数
        ArrayList<PersonRightsDto> personRightsDtos = new ArrayList<>();
        LambdaUpdateWrapper<PersonRightsVoucher> personRightsExternalLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        personRightsExternalLambdaUpdateWrapper.eq(PersonRightsVoucher::getPersonRightsId,qrCodeData.getString("personRightsId"));
        personRightsExternalLambdaUpdateWrapper.eq(PersonRightsVoucher::getExternalDataId,qrCodeData.getString("rightsExternalDataId"));
        personRightsExternalLambdaUpdateWrapper.set(PersonRightsVoucher::getStatus,1);
        personRightsExternalLambdaUpdateWrapper.setSql("times = times - " + qrCodeData.getLongValue("count"));
        personRightsVoucherService.update(personRightsExternalLambdaUpdateWrapper);
        // 修改抵扣券权益使用状态 改为 已核销
        LambdaUpdateWrapper<ProdRightsExternalData> prodRightsExternalDataLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        prodRightsExternalDataLambdaUpdateWrapper.eq(ProdRightsExternalData::getId,qrCodeData.getString("rightsExternalDataId"));
        prodRightsExternalDataLambdaUpdateWrapper.set(ProdRightsExternalData::getStatus,2);
        prodRightsExternalDataService.update(prodRightsExternalDataLambdaUpdateWrapper);
        PersonRightsDto personRightsDto = new PersonRightsDto();
        personRightsDto.setId(qrCodeData.getLongValue("personRightsId"));
        personRightsDto.setRightsId(qrCodeData.getLongValue("rightsId"));
        personRightsDto.setRemark(qrCodeData.getString("tokenId"));
        // 被核销人
        personRightsDto.setUserId(qrCodeData.getString("userId"));
        // 核销人
        personRightsDto.setHolderUserId(AuthUserContext.get().getUserId());
        personRightsDto.setTimes(qrCodeData.getLongValue("count"));
        personRightsDto.setStatus("2");
        personRightsDto.setStatusUpdate(1);
        personRightsDtos.add(personRightsDto);
        return personRightsDtos;
    }

    // 抵扣券 token转移 膨胀系数
    @Override
    public void updatePersonRights(Long rights,String personRightsId, String userId, String toUserId) {
        // 查询抵扣券权益 膨胀系数
        ProdRights prodRights = prodRightsService.getById(rights);
        boolean isReverse = false;
        if(prodRights.getIsReverse() == 0){
            // 查询领取者是否 拥有过该权益
            QueryWrapper<RightsTransferRecord> rightsTransferRecordQueryWrapper = new QueryWrapper<>();
            rightsTransferRecordQueryWrapper.eq("rights_id",rights);
            rightsTransferRecordQueryWrapper.eq("have_user",toUserId);
            List<RightsTransferRecord> list = rightsTransferRecordService.list(rightsTransferRecordQueryWrapper);
            if(ObjectUtil.isNotEmpty(list)){
                isReverse  = true;
            }
        }

        QueryWrapper<PersonRightsVoucher> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("person_rights_id",personRightsId);
        PersonRightsVoucher one = personRightsVoucherService.getOne(queryWrapper);
        if(!isReverse){
            RightsVoucher rightsVoucher = rightsVoucherService.getOne(new QueryWrapper<RightsVoucher>().eq("rights_id", rights));
            one.setExpansionData(Math.min(one.getExpansionData() * rightsVoucher.getCoefficient(), rightsVoucher.getMaxData()));
            personRightsVoucherService.updateById(one);
        }
        // 权益记录转移
        RightsTransferRecord rightsTransferRecord = new RightsTransferRecord();
        rightsTransferRecord.setPersonRightsId(Long.parseLong(personRightsId));
        rightsTransferRecord.setFinalData(one.getExpansionData());
        rightsTransferRecord.setReceiveUser(toUserId);
        rightsTransferRecord.setHaveUser(userId);
        rightsTransferRecordService.save(rightsTransferRecord);

    }

    @Override
    public void cancelOrder(Long orderNumber) {
        // 抵扣券 无 回滚次数逻辑

    }

    @Override
    public void updateRightsEffective(List<Long> rightsId) {
        // 修改过期状态
        LambdaUpdateWrapper<PersonRightsVoucher> personRightsExternalLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        personRightsExternalLambdaUpdateWrapper.in(PersonRightsVoucher::getPersonRightsId,rightsId);
        personRightsExternalLambdaUpdateWrapper.eq(PersonRightsVoucher::getStatus,0);
        personRightsExternalLambdaUpdateWrapper.set(PersonRightsVoucher::getStatus,3);
        personRightsVoucherService.update(personRightsExternalLambdaUpdateWrapper);
    }

    @Override
    public void rightsTransfer(TransferRightsEvent event) {
        // 查询抵扣券权益 膨胀系数
        ProdRights prodRights = prodRightsService.getById(event.getRightsId());
        boolean isReverse = false;
        if(prodRights.getIsReverse() == 0){
            // 查询领取者是否 拥有过该权益
            QueryWrapper<RightsTransferRecord> rightsTransferRecordQueryWrapper = new QueryWrapper<>();
            rightsTransferRecordQueryWrapper.eq("rights_id",event.getRightsId());
            rightsTransferRecordQueryWrapper.eq("have_user",event.getReceiveUser());
            List<RightsTransferRecord> list = rightsTransferRecordService.list(rightsTransferRecordQueryWrapper);
            if(ObjectUtil.isNotEmpty(list)){
                isReverse  = true;
            }
        }

        QueryWrapper<PersonRightsVoucher> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("person_rights_id",event.getPersonRightsId());
        PersonRightsVoucher one = personRightsVoucherService.getOne(queryWrapper);
        if(!isReverse){
            RightsVoucher rightsVoucher = rightsVoucherService.getOne(new QueryWrapper<RightsVoucher>().eq("rights_id", event.getRightsId()));
            one.setExpansionData(Math.min(one.getExpansionData() * rightsVoucher.getCoefficient(), rightsVoucher.getMaxData()));
            event.setFinalData(one.getExpansionData());
            personRightsVoucherService.updateById(one);
        }

    }
}
